Completed
Push — master ( e88c19...17669b )
by Rain
03:00
created

AbstractAjaxRemote.ajaxRequest   F

Complexity

Conditions 14
Paths 2048

Size

Total Lines 85

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 14
c 1
b 0
f 0
nc 2048
nop 5
dl 0
loc 85
rs 2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like AbstractAjaxRemote.ajaxRequest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
2
import window from 'window';
3
import _ from '_';
4
import $ from '$';
5
6
import {TOKEN_ERROR_LIMIT, AJAX_ERROR_LIMIT, DEFAULT_AJAX_TIMEOUT} from 'Common/Consts';
7
import {StorageResultType, Notification} from 'Common/Enums';
8
import {inArray, pInt, pString, isUnd} from 'Common/Utils';
9
import {data as GlobalsData} from 'Common/Globals';
10
import {ajax} from 'Common/Links';
11
import {runHook} from 'Common/Plugins';
12
13
import * as Settings from 'Storage/Settings';
14
15
class AbstractAjaxRemote
16
{
17
	constructor() {
18
		this.oRequests = {};
19
	}
20
21
	/**
22
	 * @param {?Function} fCallback
23
	 * @param {string} sRequestAction
24
	 * @param {string} sType
25
	 * @param {?AjaxJsonDefaultResponse} oData
26
	 * @param {boolean} bCached
27
	 * @param {*=} oRequestParameters
28
	 */
29
	defaultResponse(fCallback, sRequestAction, sType, oData, bCached, oRequestParameters) {
30
		const
31
			fCall = () => {
32
				if (StorageResultType.Success !== sType && GlobalsData.bUnload)
33
				{
34
					sType = StorageResultType.Unload;
35
				}
36
37
				if (StorageResultType.Success === sType && oData && !oData.Result)
38
				{
39
					if (oData && -1 < inArray(oData.ErrorCode, [
40
						Notification.AuthError, Notification.AccessError,
41
						Notification.ConnectionError, Notification.DomainNotAllowed, Notification.AccountNotAllowed,
42
						Notification.MailServerError, Notification.UnknownNotification, Notification.UnknownError
43
					]))
44
					{
45
						GlobalsData.iAjaxErrorCount += 1;
46
					}
47
48
					if (oData && Notification.InvalidToken === oData.ErrorCode)
49
					{
50
						GlobalsData.iTokenErrorCount += 1;
51
					}
52
53
					if (TOKEN_ERROR_LIMIT < GlobalsData.iTokenErrorCount)
54
					{
55
						if (GlobalsData.__APP__ && GlobalsData.__APP__.loginAndLogoutReload)
56
						{
57
							GlobalsData.__APP__.loginAndLogoutReload(false, true);
58
						}
59
					}
60
61
					if (oData.ClearAuth || oData.Logout || AJAX_ERROR_LIMIT < GlobalsData.iAjaxErrorCount)
62
					{
63
						if (GlobalsData.__APP__ && GlobalsData.__APP__.clearClientSideToken)
64
						{
65
							GlobalsData.__APP__.clearClientSideToken();
66
67
							if (!oData.ClearAuth && GlobalsData.__APP__.loginAndLogoutReload)
68
							{
69
								GlobalsData.__APP__.loginAndLogoutReload(false, true);
70
							}
71
						}
72
					}
73
				}
74
				else if (StorageResultType.Success === sType && oData && oData.Result)
75
				{
76
					GlobalsData.iAjaxErrorCount = 0;
77
					GlobalsData.iTokenErrorCount = 0;
78
				}
79
80
				runHook('ajax-default-response', [sRequestAction, StorageResultType.Success === sType ? oData : null, sType, bCached, oRequestParameters]);
81
82
				if (fCallback)
83
				{
84
					fCallback(
85
						sType,
86
						StorageResultType.Success === sType ? oData : null,
87
						bCached,
88
						sRequestAction,
89
						oRequestParameters
90
					);
91
				}
92
			};
93
94
		switch (sType)
95
		{
96
			case 'success':
97
				sType = StorageResultType.Success;
98
				break;
99
			case 'abort':
100
				sType = StorageResultType.Abort;
101
				break;
102
			default:
103
				sType = StorageResultType.Error;
104
				break;
105
		}
106
107
		if (StorageResultType.Error === sType)
108
		{
109
			_.delay(fCall, 300);
110
		}
111
		else
112
		{
113
			fCall();
114
		}
115
	}
116
117
	/**
118
	 * @param {?Function} fResultCallback
119
	 * @param {Object} oParameters
0 ignored issues
show
Documentation introduced by
The parameter oParameters does not exist. Did you maybe forget to remove this comment?
Loading history...
120
	 * @param {?number=} iTimeOut = 20000
121
	 * @param {string=} sGetAdd = ''
122
	 * @param {Array=} aAbortActions = []
0 ignored issues
show
Documentation Bug introduced by
The parameter aAbortActions does not exist. Did you maybe mean abortActions instead?
Loading history...
123
	 * @returns {jQuery.jqXHR}
124
	 */
125
	ajaxRequest(fResultCallback, params, iTimeOut = 20000, sGetAdd = '', abortActions = []) {
126
		const
127
			isPost = '' === sGetAdd,
128
			headers = {},
129
			start = (new window.Date()).getTime();
130
131
		let
132
			action = '';
133
134
		params = params || {};
135
		action = params.Action || '';
136
137
		if (action && 0 < abortActions.length)
138
		{
139
			_.each(abortActions, (actionToAbort) => {
140
				if (this.oRequests[actionToAbort])
141
				{
142
					this.oRequests[actionToAbort].__aborted = true;
143
					if (this.oRequests[actionToAbort].abort)
144
					{
145
						this.oRequests[actionToAbort].abort();
146
					}
147
					this.oRequests[actionToAbort] = null;
148
				}
149
			});
150
		}
151
152
		if (isPost)
153
		{
154
			params.XToken = Settings.appSettingsGet('token');
155
		}
156
157
		const oDefAjax = $.ajax({
158
			type: isPost ? 'POST' : 'GET',
159
			url: ajax(sGetAdd),
160
			async: true,
161
			dataType: 'json',
162
			data: isPost ? params : {},
163
			headers: headers,
164
			timeout: iTimeOut,
165
			global: true
166
		});
167
168
		oDefAjax.always((oData, sType) => {
169
170
			let cached = false;
171
			if (oData && oData.Time)
172
			{
173
				cached = pInt(oData.Time) > (new window.Date()).getTime() - start;
174
			}
175
176
			if (action && this.oRequests[action])
177
			{
178
				if (this.oRequests[action].__aborted)
179
				{
180
					sType = 'abort';
181
				}
182
183
				this.oRequests[action] = null;
184
			}
185
186
			this.defaultResponse(fResultCallback, action, sType, oData, cached, params);
187
		});
188
189
		if (action && 0 < abortActions.length && -1 < inArray(action, abortActions))
190
		{
191
			if (this.oRequests[action])
192
			{
193
				this.oRequests[action].__aborted = true;
194
				if (this.oRequests[action].abort)
195
				{
196
					this.oRequests[action].abort();
197
				}
198
				this.oRequests[action] = null;
199
			}
200
201
			this.oRequests[action] = oDefAjax;
202
		}
203
204
		return oDefAjax;
205
	}
206
207
	/**
208
	 * @param {?Function} fCallback
209
	 * @param {string} sAction
210
	 * @param {Object=} oParameters
211
	 * @param {?number=} iTimeout
212
	 * @param {string=} sGetAdd = ''
213
	 * @param {Array=} aAbortActions = []
214
	 */
215
	defaultRequest(fCallback, sAction, oParameters, iTimeout, sGetAdd, aAbortActions) {
216
		oParameters = oParameters || {};
217
		oParameters.Action = sAction;
218
219
		sGetAdd = pString(sGetAdd);
220
221
		runHook('ajax-default-request', [sAction, oParameters, sGetAdd]);
222
223
		return this.ajaxRequest(fCallback, oParameters,
224
			isUnd(iTimeout) ? DEFAULT_AJAX_TIMEOUT : pInt(iTimeout), sGetAdd, aAbortActions);
225
	}
226
227
	/**
228
	 * @param {?Function} fCallback
229
	 */
230
	noop(fCallback) {
231
		this.defaultRequest(fCallback, 'Noop');
232
	}
233
234
	/**
235
	 * @param {?Function} fCallback
236
	 * @param {string} sMessage
237
	 * @param {string} sFileName
238
	 * @param {number} iLineNo
239
	 * @param {string} sLocation
240
	 * @param {string} sHtmlCapa
241
	 * @param {number} iTime
242
	 */
243
	jsError(fCallback, sMessage, sFileName, iLineNo, sLocation, sHtmlCapa, iTime) {
244
		this.defaultRequest(fCallback, 'JsError', {
245
			'Message': sMessage,
246
			'FileName': sFileName,
247
			'LineNo': iLineNo,
248
			'Location': sLocation,
249
			'HtmlCapa': sHtmlCapa,
250
			'TimeOnPage': iTime
251
		});
252
	}
253
254
	/**
255
	 * @param {?Function} fCallback
256
	 * @param {string} sType
257
	 * @param {Array=} mData = null
258
	 * @param {boolean=} bIsError = false
259
	 */
260
	jsInfo(fCallback, sType, mData, bIsError = false) {
261
		this.defaultRequest(fCallback, 'JsInfo', {
262
			'Type': sType,
263
			'Data': mData,
264
			'IsError': bIsError ? '1' : '0'
265
		});
266
	}
267
268
	/**
269
	 * @param {?Function} fCallback
270
	 */
271
	getPublicKey(fCallback) {
272
		this.defaultRequest(fCallback, 'GetPublicKey');
273
	}
274
275
	/**
276
	 * @param {?Function} fCallback
277
	 * @param {string} sVersion
278
	 */
279
	jsVersion(fCallback, sVersion) {
280
		this.defaultRequest(fCallback, 'Version', {
281
			'Version': sVersion
282
		});
283
	}
284
}
285
286
export {AbstractAjaxRemote, AbstractAjaxRemote as default};
287